home *** CD-ROM | disk | FTP | other *** search
Text File | 1997-07-16 | 4.5 KB | 136 lines | [TEXT/CWIE] |
- // ===========================================================================
- // CEdge.cp ©1995-97 Timo Eloranta All rights reserved.
- // ===========================================================================
- // A simple edge class. Most functions in the header (inlined).
-
- #include "CEdge.h"
- #include "MyUtils.h"
-
- #include <algobase.h> // MSL - min & max
-
- // ---------------------------------------------------------------------------
- // • Intersects
- //
- // Called by: CGraphDrawing::SimpleCountSect
- // CGraphDrawing::SmarterCountSect
- // ---------------------------------------------------------------------------
- // Return true if this edge intersects the given edge (inEdge).
- // Otherwise return false. If you know how this function could be
- // improved, please let me know, since TimGA uses this function A LOT...
-
- Boolean
- CEdge::Intersects( const CEdge & inEdge) const
- {
- Int16 p1x, p2x, p3x, p4x, xMin12, xMax12, xMin34, xMax34,
- p1y, p2y, p3y, p4y, yMin12, yMax12, yMin34, yMax34;
-
- // p1x and p1y are the x- and y-coordinates of this edge's 1st node
- // p2x and p2y are the x- and y-coordinates of this edge's 2nd node
- // ...
-
- mNode1 -> GetNodePos( p1x, p1y );
- mNode2 -> GetNodePos( p2x, p2y );
-
- inEdge.mNode1 -> GetNodePos( p3x, p3y );
- inEdge.mNode2 -> GetNodePos( p4x, p4y );
-
- //
- // Stage 1: Quick Rejection Test
- //
- // Line segments cannot intersect if their
- // bounding boxes do not intersect
- //
-
- if ( (xMax12 = max(p1x, p2x)) < (xMin34 = min(p3x, p4x)) ||
- (xMax34 = max(p3x, p4x)) < (xMin12 = min(p1x, p2x)) ||
- (yMax12 = max(p1y, p2y)) < (yMin34 = min(p3y, p4y)) ||
- (yMax34 = max(p3y, p4y)) < (yMin12 = min(p1y, p2y)) )
- return false;
-
- // The following is my own addition to the quick
- // rejection phase resulting from the fact that I don't
- // consider it an intersection if two edges share an
- // endpoint (node) but have no other shared points.
-
- if ( ( xMax12 == xMin34 && xMin12 < xMax12 && xMin34 < xMax34 ) ||
- ( xMin12 == xMax34 && xMin12 < xMax12 && xMin34 < xMax34 ) ||
- ( yMax12 == yMin34 && yMin12 < yMax12 && yMin34 < yMax34 ) ||
- ( yMin12 == yMax34 && yMin12 < yMax12 && yMin34 < yMax34 ) )
- return false;
-
- //
- // Stage 2: Determining whether both segments straddle
- // the line containing the other
- //
- // See pp. 889-890 in "Introduction to Algorithms"
- // by Cormen, Leiserson and Rivest (1990)
- //
-
- // First we'll test if the segment with endpoints p3 and p4
- // straddles the line containing the points p1 and p2
-
- Int32 crossp1 = ((p3x - p1x) * (p2y - p1y)) -
- ((p2x - p1x) * (p3y - p1y));
- Int32 crossp2 = ((p4x - p1x) * (p2y - p1y)) -
- ((p2x - p1x) * (p4y - p1y));
-
- Int32 crossp12 = crossp1 * crossp2;
-
- // Are the signs of the cross products different?
-
- if ( crossp12 > 0 ) // Segment does not straddle
- return false; // We are done!
-
- if ( crossp1 == 0 && crossp2 == 0) // Segments are collinear
- return true; // and must intersect...
-
- // Next we'll handle the case where other of the cross products
- // equals zero (but not both). This means that either p3 or p4 is on
- // the same line as both p1 and p2. *I* do not count this as straddling
- // if the point in question is an endpoint of both edges...
-
- if ( crossp12 == 0 && HasMutualNode( inEdge ) )
- return false;
-
- // If we are still here, segment with points p3 and p4 does straddle
- // the line containing points p1 and p2. For the segments to intersect
- // also the segment with p1 and p2 must straddle the line containing
- // points p3 and p4...
-
- crossp1 = ((p1x - p3x) * (p4y - p3y)) -
- ((p4x - p3x) * (p1y - p3y));
- crossp2 = ((p2x - p3x) * (p4y - p3y)) -
- ((p4x - p3x) * (p2y - p3y));
-
- crossp12 = crossp1 * crossp2;
-
- if ( crossp12 > 0 ) return false; // Segment does not straddle
- if ( crossp12 < 0 ) return true; // Segment straddles
-
- return (! HasMutualNode( inEdge ));
- }
-
- // ---------------------------------------------------------------------------
- // • Draw
- //
- // Called by: CGraphDrawing::DrawEdges
- // ---------------------------------------------------------------------------
- // Draw this edge.
-
- void
- CEdge::Draw(
- Int16 inOneOneXY, // The x- and y-coordinate of the
- // centerpoint of the (1,1) square
- Int16 inSquareSize ) const // The size of a square in pixels
- {
- Int16 p1x, p2x, p1y, p2y;
-
- mNode1 -> GetNodePos( p1x, p1y );
- mNode2 -> GetNodePos( p2x, p2y );
-
- LineFromTo ( inOneOneXY + (p1x - 1) * inSquareSize,
- inOneOneXY + (p1y - 1) * inSquareSize,
- inOneOneXY + (p2x - 1) * inSquareSize,
- inOneOneXY + (p2y - 1) * inSquareSize );
- }
-